﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;
using System.Threading;
using HMS.Common;

namespace HMS.Security
{
    public class HMSAuthenticationModule : IHttpModule
    {
        HttpApplication app = null;

        public void Dispose()
        {
        }

        /// <summary>
        /// Initializes the module derived from IHttpModule when called by the HttpRuntime . 
        /// </summary>
        /// <param name="httpapp">The HttpApplication module</param>
        public void Init(HttpApplication httpapp)
        {
            this.app = httpapp;
            app.AuthenticateRequest += new EventHandler(this.OnAuthenticate);
            app.EndRequest += new EventHandler(this.OnEndRequest);
        }

        public void OnEndRequest(object sender, EventArgs e)
        {
            var context = new HttpContextWrapper(HttpContext.Current);
            if (context.Response.StatusCode == 302 && IsAjaxCall())
            {
                context.Response.StatusCode = 401;
            }
        }

        public bool IsAjaxCall()
        {
            return string.Equals("XMLHttpRequest", HttpContext.Current.Request.Headers["x-requested-with"], StringComparison.OrdinalIgnoreCase);
        }

        void OnAuthenticate(object sender, EventArgs e)
        {
            app = (HttpApplication)sender;
            HttpRequest req = app.Request;
            HttpResponse res = app.Response;

            string loginUrl = ConfigurationSettings.AppSettings[Constants.LOGINURL_KEY];
            if (loginUrl == null || loginUrl.Trim() == String.Empty)
            {
                throw new Exception(" CustomAuthentication.LoginUrl entry not found in appSettings section of Web.config");
            }

            string cookieName = ConfigurationSettings.AppSettings[Constants.AUTHENTICATION_COOKIE_KEY];
            if (cookieName == null || cookieName.Trim() == String.Empty)
            {
                throw new Exception(" CustomAuthentication.Cookie.Name entry not found in appSettings section section of Web.config");
            }

            string cookieExpr = ConfigurationSettings.AppSettings[Constants.AUTHENTICATION_COOKIE_EXPIRATION_KEY];

            int i = req.Path.LastIndexOf("/");
            string page = req.Path.Substring(i + 1, (req.Path.Length - (i + 1)));

            int j = loginUrl.LastIndexOf("/");
            string loginPage = loginUrl.Substring(j + 1, (loginUrl.Length - (j + 1)));

            string extension = string.IsNullOrWhiteSpace(page) ? string.Empty : page.Substring(page.LastIndexOf(".") + 1).ToLower();
            if (extension == "aspx")
            {
                if (!page.Trim().ToUpper().Equals(loginPage.ToUpper()))
                {
                    if (req.Cookies.Count > 0 && req.Cookies[cookieName.ToUpper()] != null)
                    {
                        HttpCookie cookie = req.Cookies[cookieName.ToUpper()];
                        if (cookie != null)
                        {
                            HMSIdentity userIdentity = HMSAuthentication.Decrypt(cookie.Value);
                            HMSPrincipal principal = new HMSPrincipal(userIdentity);
                            app.Context.User = principal;
                            Thread.CurrentPrincipal = principal;
                            cookie.Expires = DateTime.Now.AddMinutes(int.Parse(cookieExpr));
                            HttpContext.Current.Response.Cookies.Add(cookie);
                        }
                    }
                    else
                    {
                        res.Redirect(req.ApplicationPath + loginUrl + "?ReturnUrl=" + req.Path, true);               
                    }
                }
            }
        }
    }
}
